﻿<%
'''底层ini文件读写类
Class Ashapo_Ini_Class

	'内部使用Fso名称
	Private s_fso
	'内部使用的Stream组件名
	Private s_stm

	'要打开的ini文件地址,支持绝对路径和相对路径
	Private s_path
	
	'''构造
	Private Sub Class_Initialize()
		Dim t_o : t_o = C_FSO_NAME
		Set s_fso = Server.CreateObject(t_o)
		s_stm = C_STREAM_NAME
	End Sub
	
	'''析构
	Private Sub Class_Terminate()
		Set s_fso = Nothing
	End Sub
	
	'''设置ini的路径
	Public Property Let Path(Byval p_path)
		If InStr(p_path, ":\") = 0 And Left(p_path,2)<>"\\" Then
			s_path = Server.MapPath(p_path)
		Else
			s_path = p_path
		End If
	End Property
	
	'''读取服务器端文件内容(不存在则返回空字符串)
	'p_p:文件真实地址
	Private Function readFile_(Byval p_p)
		If s_fso.FileExists(p_p) Then
			Dim t_s, t_t
			Set t_s = Server.CreateObject(s_stm)
			With t_s
				.Type = 2
				.Mode = 3
				.Open
				.LoadFromFile p_p
				.Charset = "UTF-8"
				.Position = 2
				t_t = .ReadText
				.Close
			End With
			Set t_s = Nothing
			If RegTest(t_t,"^\uFEFF") Then
				t_t = RegReplace(t_t,"^\uFEFF","")
			End If
			readFile_ = t_t
		Else
			readFile_ = ""
		End If
	End Function

	'''在服务器端创建文件并写入内容
	'p_p:文件路径
	'p_c:写入内容
	Private Sub writeFile_(Byval p_p, Byval p_c)
		On Error Resume Next
		Dim t_sm
		Set t_sm = Server.CreateObject(s_stm)
			With t_sm
				.Type = 2
				.Open
				.Charset = "UTF-8"
				.Position = t_sm.Size
				.WriteText = p_c
				.SaveToFile p_p, 2
				.Close
			End With
		Set t_sm = Nothing
		If Err.Number<>0 Then
			'抛出错误
			SE(111)
		End If
		Err.Clear()
	End Sub
	
	'''从文本中获取p_start到p_end中间的内容
	'p_content:要读取的字符串
	'p_start:开始截取的字符串
	'p_end:结束截取的字符串
	Private Function separate_(Byval p_content, Byval p_start, Byval p_end)
		Dim t_b: t_b = InStr(1, p_content, p_start, 1)
		If t_b > 0 Then
			t_b = t_b + Len(p_start)
			Dim t_e : t_e = InStr(t_b, p_content, p_end, 1)
			If t_e = 0 Then
				t_e = InStr(t_b, p_content, vbCrLf, 1)
			End If
			If t_e = 0 Then
				t_e = Len(p_content) + 1
			End If
			separate_ = Mid(p_content, t_b, t_e - t_b)
		End If
	End Function
	
	'''获取INI键值
	'p_section:节点
	'p_key:键名
	'p_default:获取不到时的默认值
	Public Function [Get](Byval p_section, Byval p_key, Byval p_default)
		Dim t_icontent, t_sstart, t_send, t_scontent, t_value, t_t_found
		t_icontent = readFile_(s_path)
		'寻找节点
		t_sstart = InStr(1, t_icontent, "[" & p_section & "]", 1)
		If t_sstart>0 Then
			'找到节点，寻找节点结束点
			t_send = InStr(t_sstart, t_icontent, vbCrLf & "[")
			'最后一个节点的情况
			If t_send = 0 Then
				t_send = Len(t_icontent) + 1
			End If
			'节点下的所有键值对内容
			t_scontent = Mid(t_icontent, t_sstart, t_send - t_sstart)
			If InStr(1, t_scontent, vbCrLf & p_key & "=", 1)>0 Then
				t_t_found = True
				'获得值
				t_value = separate_(t_scontent, vbCrLf & p_key & "=", vbCrLf)
			End If
		End If
		If IsEmpty(t_t_found) Then
			t_value = p_default
		End If
		[Get] = t_value
	End Function

	'''设置ini键值
	Public Sub [Set](Byval p_section, Byval p_key, Byval p_value)
		Dim t_icontent, t_sstart, t_send
		t_icontent = readFile_(s_path)
		'寻找节点
		t_sstart = InStr(1, t_icontent, "[" & p_section & "]", 1)
		If t_sstart>0 Then
			'找到节点，寻找节点结束点
			t_send = InStr(t_sstart, t_icontent, vbCrLf & "[")
			'最后一个节点的情况
			If t_send = 0 Then
				t_send = Len(t_icontent) + 1
			End If
			'节点下的所有键值对内容
			Dim t_old, t_new, t_line
			Dim t_key, t_found
			t_old = Mid(t_icontent, t_sstart, t_send - t_sstart)
			t_old = Split(t_old, vbCrLf)
			t_key = LCase(p_key & "=")
			'改写每一行
			For Each t_line In t_old
				If LCase(Left(t_line, Len(t_key))) = t_key Then
					t_line = p_key & "=" & p_value
					t_found = True
				End If
				t_new = t_new & t_line & vbCrLf
			Next
			If IsEmpty(t_found) Then
				'如果没有找到键值则在后面追加
				t_new = t_new & p_key & "=" & p_value
			Else
				'处理最后一个vbCrLf
				t_new = Left(t_new, Len(t_new) - 2)
			End If
			'组装文本
			t_icontent = Left(t_icontent, t_sstart-1) & t_new & Mid(t_icontent, t_send)
		Else
			'如果没找到节点则直接在文本后面追加
			If Right(t_icontent, 2) <> vbCrLf And Len(t_icontent)>0 Then 
				t_icontent = t_icontent & vbCrLf 
			End If
			t_icontent = t_icontent & "[" & p_section & "]" & vbCrLf & p_key & "=" & p_value
		End If
		Call writeFile_(s_path, t_icontent)
	End Sub
End Class
%>